﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static System.Threading.Thread;
using static System.Console;

namespace Project_1
{
    /// <summary>
    /// 1.10 线程锁,lock关键字
    /// </summary>
    public class Unit_1_10
    {
        /*
         * Object locker = new Object();
         * lock(locker)
         * {
         *  上锁的代码，同一时刻，只能有一个线程运行上锁的代码，
         *  不然其它线程使用了该线程运行之前的值，导致数据异常
         * }
         */
        public static void Go()
        {
            WriteLine("不加锁的计数器开始");
            var c=new Counter();
            ExecCounter(c);
            WriteLine("");
            WriteLine("------------------------------------------------------");
            WriteLine("加锁的计数器开始");
            var c1=new CounterWithLock();
            ExecCounter(c1);

            WriteLine("");
            WriteLine("------------------------------------------------------");
            WriteLine($" 不加锁的计数器 计算结果 : {c.Count} ");
            WriteLine("------------------------------------------------------");
            WriteLine($" 加锁的计数器 计算结果 : {c1.Count} ");

        }

        /// <summary>
        /// 多线程执行计数器
        /// </summary>
        static void ExecCounter(CounterBase c)
        {
            var t1 = new Thread(() => TestCounter(c));
            var t2 = new Thread(() => TestCounter(c));
            var t3 = new Thread(() => TestCounter(c));
            t1.Start();
            t2.Start();
            t3.Start();
            //t1.Join() 方法，主线程会停止，等待t1线程执行结束完成后再开始
            t1.Join();
            t2.Join();
            t3.Join();
        }

        /// <summary>
        /// 调用计数器的加减方法
        /// </summary>
        /// <param name="c">计数器类</param>
        static void TestCounter(CounterBase c)
        {
            for (int i = 0; i < 300; i++)
            {
                c.Increment();
                c.Decrement();
            }
        }

        /// <summary>
        /// 加锁的计数器类
        /// </summary>
        class CounterWithLock:CounterBase
        {
            private readonly object dsa=new object();

            public int Count { get; private set; }

            public override void Increment()
            {
                lock (dsa)
                {
                    Count++;
                    Write($" {Count} ");
                }
            }

            public override void Decrement()
            {
                lock (dsa)
                {
                    Count--;
                    Write($" {Count} ");
                }
            }
        }

        /// <summary>
        /// 不加锁的计数器类
        /// </summary>
        class Counter:CounterBase
        {
            public int Count { get; private set; }

            public override void Increment()
            {
                Count++;
                Write($" {Count} ");
            }

            public override void Decrement()
            {
                Count--;
                Write($" {Count} ");
            }
        }

        /// <summary>
        /// 计数器类,抽象类
        /// </summary>
        abstract class CounterBase
        {
            public abstract void Increment();//增加
            public abstract void Decrement();//减少
        }

    }
}
